package com.example.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.example.common.CustomException;
import com.example.common.ResultCode;
import com.example.dao.GoodsInfoDao;
import com.example.dao.OrderGoodsRelDao;
import com.example.dao.OrderInfoDao;
import com.example.dto.OrderPageDTO;
import com.example.entity.*;
import com.example.util.OrderWebSocketHandler;
import com.example.util.ResponseCode;
import com.example.util.ResponseData;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class OrderInfoService {

    @Resource
    private OrderInfoDao orderInfoDao;
    @Resource
    private GoodsInfoService goodsInfoService;
	@Resource
	private UserInfoService userInfoService;

    @Resource
    private OrderGoodsRelDao orderGoodsRelDao;
    @Resource
    private CartInfoService cartInfoService;
    @Resource
    private OrderQsService orderQsService;
    @Resource
    private TableService tableService;
    @Resource
    private GoodsInfoDao goodsInfoDao;


    /**
     * 查询某个用户的所有订单
     * @param userId
     * @param level
     * @return
     */
    public List<OrderInfo> findAll(Long userId, Integer level) {
        List<OrderInfo> orderInfos = orderInfoDao.findByUserId(userId, level);
        for (OrderInfo orderInfo : orderInfos) {
            packOrder(orderInfo);
        }
        return orderInfos;
    }

    /**
     * 包装订单的用户和菜品信息
     */
    private void packOrder(OrderInfo orderInfo) {
        Long orderId = orderInfo.getId();
        List<OrderGoodsRel> rels = orderGoodsRelDao.findByOrderId(orderId);
        orderInfo.setUserInfo(getUserInfo(orderInfo.getUserId(), orderInfo.getLevel()));
        List<GoodsInfo> goodsList = CollUtil.newArrayList();
        orderInfo.setGoodsList(goodsList);
        for (OrderGoodsRel rel : rels) {
            GoodsInfo goodsDetailInfo = goodsInfoService.findById(rel.getGoodsId());
            if (goodsDetailInfo != null) {
                // 注意这里返回的count是用户加入菜品的数量，而不是菜品的库存
                goodsDetailInfo.setCount(rel.getCount());
                goodsList.add(goodsDetailInfo);
            }
        }
    }

    /**
     * 分页查询订单信息
     * 包括模糊查询
     */
    public PageInfo<OrderInfo> findEndPages(OrderPageDTO orderPageDTO) {
        Integer pageIndex = orderPageDTO.getPageIndex();
        Integer pageSize = orderPageDTO.getPageSize();
        String status = orderPageDTO.getStatus();
        Integer orderType = orderPageDTO.getOrderType();
        PageHelper.startPage(pageIndex, pageSize);
        //List<OrderInfo> orderInfos = this.orderInfoDao.selectAll();

        List<OrderInfo> orderInfos = this.orderInfoDao.queryAmbi(status, orderType);
        for (OrderInfo orderInfo : orderInfos) {
            packOrder(orderInfo);
        }
        return PageInfo.of(orderInfos);
    }

//    /**
//     * 分页查询订单信息
//     */
//    public PageInfo<OrderInfo> findEndPages(Integer pageNum, Integer pageSize, HttpServletRequest request) {
//        Account user = (Account) request.getSession().getAttribute("user");
//        if (user == null) {
//            throw new CustomException("1001", "session已失效，请重新登录");
//        }
//        Integer level = user.getLevel();
//        Long userId = user.getId();
//        PageHelper.startPage(pageNum, pageSize);
//        List<OrderInfo> orderInfos;
//        if (1 == level) {
//            orderInfos = orderInfoDao.selectAll();
//        } else if (userId != null){
//            orderInfos = orderInfoDao.findByEndUserId(userId, null, level);
//        } else {
//            orderInfos = new ArrayList<>();
//        }
//        for (OrderInfo orderInfo : orderInfos) {
//            packOrder(orderInfo);
//        }
//        return PageInfo.of(orderInfos);
//    }

    public PageInfo<OrderInfo> findFrontPages(Long userId, Integer level, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<OrderInfo> orderInfos;
        if (userId != null){
            orderInfos = orderInfoDao.findByUserId(userId, level);
        } else {
            orderInfos = new ArrayList<>();
        }
        for (OrderInfo orderInfo : orderInfos) {
            packOrder(orderInfo);
        }
        return PageInfo.of(orderInfos);
    }

    /**
     * 分页查询订单信息
     */
    public PageInfo<OrderInfo> findPages(Long userId, Integer level, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<OrderInfo> orderInfos;
        if (userId != null) {
            orderInfos = orderInfoDao.findByUserId(userId, level);
        } else {
            orderInfos = orderInfoDao.selectAll();
        }
        for (OrderInfo orderInfo : orderInfos) {
            packOrder(orderInfo);
        }
        return PageInfo.of(orderInfos);
    }

    /**
     * 下单（新）
     */
    @Transactional
    public OrderInfo add1(OrderInfo info) {
        Double totalPrice1 = info.getTotalPrice();
        Long userId = info.getUserId();
        Integer level = info.getLevel();
        Account userInfo = getUserInfo(userId, level);
        Integer orderType = info.getOrderType();
        List<GoodsInfo> goodsList = info.getGoodsList();

        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setUserId(userId);
        orderInfo.setLevel(level);
        orderInfo.setStatus("待付款");
        orderInfo.setOrderType(orderType);
//        orderInfo.setLinkAddress(userInfo.getAddress());
//        orderInfo.setLinkMan(userInfo.getNickName());
//        orderInfo.setLinkPhone(userInfo.getPhone());
        orderInfo.setCreateTime(DateUtil.formatDateTime(new Date()));

        // 生成订单
        orderInfoDao.insertSelective(orderInfo);

        double totalPrice = 0;
        for (GoodsInfo orderGoodsVO : goodsList) {
            Long goodsId = orderGoodsVO.getId();
            // 查询菜品信息
            GoodsInfo goodsDetail = goodsInfoService.findById(goodsId);
            if (goodsDetail != null) {
                Integer orderCount = orderGoodsVO.getCount() == null ? 0 : orderGoodsVO.getCount();
                Integer goodsCount = goodsDetail.getCount() == null ? 0 : goodsDetail.getCount();

                // 扣库存
                if (orderCount <= goodsCount) {
                    goodsDetail.setCount(goodsCount - orderCount);
                    // 销量 +count
                    int sales = goodsDetail.getSales() == null ? 0 : goodsDetail.getSales();
                    goodsDetail.setSales(sales + orderCount);
                    goodsInfoService.update(goodsDetail);

                    // 建立关系
                    OrderGoodsRel orderGoodsRel = new OrderGoodsRel();
                    orderGoodsRel.setGoodsId(goodsId);
                    orderGoodsRel.setOrderId(orderInfo.getId());
                    orderGoodsRel.setCount(orderCount);
                    orderGoodsRelDao.insertSelective(orderGoodsRel);

                    totalPrice += goodsDetail.getPrice() * orderCount;
                }
            }
        }
        orderInfo.setTotalPrice(totalPrice1);

        // 更新订单信息
        orderInfoDao.updateByPrimaryKeySelective(orderInfo);

        // 下单 清空购物车
        cartInfoService.empty(userId, level);

        packOrder(orderInfo);
        return orderInfo;
    }

    /**
     * 下单
     */
    @Transactional
    public OrderInfo add(OrderInfo info) {
        Long userId = info.getUserId();
        Integer level = info.getLevel();
        Account userInfo = getUserInfo(userId, level);
        Integer orderType = info.getOrderType();
        List<GoodsInfo> goodsList = info.getGoodsList();
        // 将菜品分分类，根据上传用户id_用户level来确定唯一的key
        Map<String, List<GoodsInfo>> collectMap = goodsList.stream()
                .collect(Collectors.groupingBy(x -> x.getUserId() + "_" + x.getLevel()));

        OrderInfo lastOrderInfo = null;  // 用于存储最后创建的订单

        for (String key : collectMap.keySet()) {
            List<GoodsInfo> list = collectMap.get(key);
            // 这里面创建一个订单
            OrderInfo orderInfo = new OrderInfo();
            orderInfo.setUserId(userId);
            orderInfo.setLevel(level);
            orderInfo.setStatus("待付款");
            orderInfo.setOrderType(orderType);
            orderInfo.setLinkAddress(userInfo.getAddress());
            orderInfo.setLinkMan(userInfo.getNickName());
            orderInfo.setLinkPhone(userInfo.getPhone());
            orderInfo.setCreateTime(DateUtil.formatDateTime(new Date()));

            // 生成订单
            orderInfoDao.insertSelective(orderInfo);

            double totalPrice = 0;
            for (GoodsInfo orderGoodsVO : list) {
                Long goodsId = orderGoodsVO.getId();
                // 查询菜品信息
                GoodsInfo goodsDetail = goodsInfoService.findById(goodsId);
                if (goodsDetail != null) {
                    Integer orderCount = orderGoodsVO.getCount() == null ? 0 : orderGoodsVO.getCount();
                    Integer goodsCount = goodsDetail.getCount() == null ? 0 : goodsDetail.getCount();

                    // 扣库存
                    if (orderCount <= goodsCount) {
                        goodsDetail.setCount(goodsCount - orderCount);
                        // 销量 +count
                        int sales = goodsDetail.getSales() == null ? 0 : goodsDetail.getSales();
                        goodsDetail.setSales(sales + orderCount);
                        goodsInfoService.update(goodsDetail);

                        // 建立关系
                        OrderGoodsRel orderGoodsRel = new OrderGoodsRel();
                        orderGoodsRel.setGoodsId(goodsId);
                        orderGoodsRel.setOrderId(orderInfo.getId());
                        orderGoodsRel.setCount(orderCount);
                        orderGoodsRelDao.insertSelective(orderGoodsRel);

                        totalPrice += goodsDetail.getPrice() * orderCount;
                    }
                }
            }
            orderInfo.setTotalPrice(totalPrice);
            // 更新订单信息
            orderInfoDao.updateByPrimaryKeySelective(orderInfo);

            // 将当前创建的订单对象赋值给 lastOrderInfo
            lastOrderInfo = orderInfo;

            // 下单 清空购物车
            cartInfoService.empty(userId, level);
        }
        packOrder(lastOrderInfo);
        return lastOrderInfo;
    }


    @Transactional(rollbackFor = Exception.class)
    public void add(Long userId, Integer level, List<GoodsInfo> goodsList,Integer orderType) {

        Account userInfo = getUserInfo(userId, level);

        for (GoodsInfo orderGoodsVO : goodsList) {
            OrderInfo orderInfo = new OrderInfo();
            orderInfo.setOrderType(orderType);//设置餐饮类型。1堂食0外卖
            orderInfo.setLinkAddress(userInfo.getAddress());
            orderInfo.setLinkMan(userInfo.getNickName());
            orderInfo.setLinkPhone(userInfo.getPhone());
            orderInfo.setCreateTime(DateUtil.formatDateTime(new Date()));
            orderInfo.setUserId(userId);
            orderInfo.setStatus("待付款");

            // 订单id：用户id + 当前年月日时分 + 4位流水号
            String orderId = userId + DateUtil.format(new Date(), "yyyyMMddHHmm") + RandomUtil.randomNumbers(4);
            //orderInfo.setOrderId(orderId);

            Long goodsId = orderGoodsVO.getId();
            // 查询菜品信息
            GoodsInfo goodsDetail = goodsInfoService.findById(goodsId);
            if (goodsDetail != null) {
                Integer orderCount = orderGoodsVO.getCount() == null ? 0 : orderGoodsVO.getCount();
                orderInfo.setTotalPrice(orderCount * goodsDetail.getPrice());
                // 生成订单
                orderInfoDao.insertSelective(orderInfo);

                Integer goodsCount = goodsDetail.getCount() == null ? 0 : goodsDetail.getCount();

                // 扣库存
                if (orderCount > goodsCount) {
                    throw new CustomException(ResultCode.ORDER_PAY_ERROR);
                }
                goodsDetail.setCount(goodsCount - orderCount);
                // 销量 +count
                int sales = goodsDetail.getSales() == null ? 0 : goodsDetail.getSales();
                goodsDetail.setSales(sales + orderCount);
                goodsInfoService.update(goodsDetail);

                // 建立关系
                OrderGoodsRel orderGoodsRel = new OrderGoodsRel();
                orderGoodsRel.setGoodsId(goodsId);
                orderGoodsRel.setOrderId(orderInfo.getId());
                orderGoodsRel.setCount(orderCount);
                orderGoodsRelDao.insertSelective(orderGoodsRel);
            }
        }

        // 下单 清空购物车
        cartInfoService.empty(userId, level);
    }

    @Transactional
    public void delete(Long id) {
        orderInfoDao.deleteById(id);
        orderGoodsRelDao.deleteByOrderId(id);
    }

    public void deleteGoods(Long goodsId, Long orderId) {
        orderGoodsRelDao.deleteByGoodsIdAndOrderId(goodsId, orderId);
    }

    public OrderInfo findByOrderId(Long orderId) {
        return orderInfoDao.findById(orderId);
    }

    /**
     * 修改订单状态
     * 1. 待付款
     * 2. 已付款
     * 3. 已完成
     * @param id
     * @param status
     */
    public void changeStatus(Long id, String status) {
        this.orderInfoDao.updateStatus(id, status);
    }

    private Account getUserInfo(Long userId, Integer level) {
        Account account = new Account();
        account = this.userInfoService.findById(userId);
        return account;
    }


    public ResponseData queryOrderInfoByStatus() {
        ResponseData responseData = new ResponseData(ResponseCode.SUCCESS01, orderInfoDao.queryOrderInfoByStatus());
        return responseData;
    }

    public ResponseData updataState(String i) {
        ResponseData responseData=new ResponseData(orderInfoDao.updataState(i));
        return responseData;
    }

    public ResponseData queryOrderInfoByOrderId(String orderId) {
        ResponseData responseData=new ResponseData(orderInfoDao.queryOrderInfoByOrderId(orderId));
        return  responseData;
    }


    /**
     * 查询所有的订单信息（包括订单中的菜品列表)
     * @return
     */
    public List<OrderInfo> getAllOrderInfoWithGoods() {
        List<OrderInfo> orderInfos = this.orderInfoDao.selectAll();
        for (int i = 0; i < orderInfos.size(); i++) {
            this.packOrder(orderInfos.get(i));
        }
        return orderInfos;
    }

    /**
     * 根据id查询订单信息
     */
    public OrderInfo findById(Long id) {
        OrderInfo orderInfo = this.orderInfoDao.selectByPrimaryKey(id);
        this.packOrder(orderInfo);
        return orderInfo;
    }

    /**
     * 删除订单
     * @param id
     */
    public void deleteOrderById(Long id) {
        this.orderGoodsRelDao.deleteByOrderId(id);
        this.orderInfoDao.deleteById(id);
    }

    /**
     * 选择堂食还是外卖
     * @param id
     * @param orderType
     */
    public void placeOrder(Long id, Integer orderType) {
        int i = this.orderInfoDao.placeOrder(id, orderType);
        if (i < 0) {
            throw new CustomException(ResultCode.ORDER_PAY_ERROR);
        }
    }

    /**
     * 根据订单id修改订单信息
     * @param orderInfo
     * @return
     */
    @Transactional
    public OrderInfo updateOrder(OrderInfo orderInfo) {
        if (orderInfo.getId() == null) {
            throw new IllegalArgumentException("订单ID不能为空");
        }
        //如果修改的是订单桌位号
        if (orderInfo.getTableId() != null){
            //占用桌位
            Table t = new Table();
            t.setId(orderInfo.getTableId());
            t.setStatus(String.valueOf(1));
            this.tableService.update(t);
        }
        OrderInfo byId = this.findById(orderInfo.getId());
        if (byId != null && orderInfo.getStatus() != null) {
            //如果是修改订单状态为已付款且类型是外卖
            if (orderInfo.getStatus().equals("已付款") && byId.getOrderType() == 0){
                //生成骑手订单
                OrderQs orderQs = new OrderQs();
                orderQs.setStatus("待派送");
                orderQs.setOrderid(String.valueOf(orderInfo.getId()));
                this.orderQsService.insert(orderQs);
                OrderWebSocketHandler.sendMessageToAll("您有新的外卖订单");
            }
            //如果是修改订单状态为已付款且类型是堂食
            if ((orderInfo.getStatus().equals("已付款") && byId.getOrderType() == 1) || orderInfo.getStatus().equals("已关闭")){
                //如果是堂食已付款
                if (orderInfo.getStatus().equals("已付款") && byId.getOrderType() == 1){
                    orderInfo.setStatus("已完成");
                }
                //释放桌位
                Table t = new Table();
                t.setId(byId.getTableId());
                t.setStatus(String.valueOf(0));
                this.tableService.update(t);
                OrderWebSocketHandler.sendMessageToAll("您有新的堂食订单");
            }
            //如果是关闭订单，要释放菜品库存
            if (orderInfo.getStatus().equals("已关闭")){
                OrderInfo order1 = this.findById(orderInfo.getId());
                List<GoodsInfo> goodsList = order1.getGoodsList();
                //释放菜品库存
                for (GoodsInfo goods : goodsList) {
                    Long id = goods.getId();
                    Integer count = goods.getCount();
                    GoodsInfo goods1 = this.goodsInfoDao.findById1(id);
                    System.out.println(goods1.getCount());
                    goods1.setCount(goods1.getCount() + count);
                    this.goodsInfoService.update(goods1);
                }
            }
        }
        int rowsAffected = orderInfoDao.updateByPrimaryKeySelective(orderInfo);
        if (rowsAffected > 0) {
            return orderInfoDao.selectByPrimaryKey(orderInfo.getId());
        } else {
            return null;
        }
    }

    /**
     * 获取用户上一次下单的订单信息
     * @param userId
     * @return
     */
    public OrderInfo getOnce(Long userId) {
        OrderInfo lastOrderByUserId = this.orderInfoDao.findLastOrderByUserId(userId);
        if (lastOrderByUserId != null){
            packOrder(lastOrderByUserId);
        }
        return lastOrderByUserId;
    }

    //获取2024年营业总额
    public Double getTotalYear() {
        Double a = this.orderInfoDao.getAllPrice();
        return a;
    }

    //获取2024年6月份的营业额
    public Double getTotalMonth() {
        Double a = this.orderInfoDao.getAllPriceByMonth();
        return a;
    }

    @Scheduled(fixedRate = 60000) // 每分钟检查一次
    public void checkOrderTimeout() {
        LocalDateTime now = LocalDateTime.now().minusMinutes(30);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String timeoutThreshold = now.format(formatter);

        // 查询超时订单
        List<OrderInfo> timeoutOrders = orderInfoDao.findOrdersByCreateTimeBefore(timeoutThreshold);

        for (OrderInfo order : timeoutOrders) {
            if ("待付款".equals(order.getStatus())) {
                OrderWebSocketHandler.sendMessageToAll("订单超时：" + order.getId());
            }
        }
    }

}
